package com.tianji.learning.utils;
import lombok.Data;
import java.time.Duration;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;


//Delayed类型的延迟任务类
@Data
public class DelayTask<D> implements Delayed {
    //任务需要的相关信息，不确定所以使用泛型。
    private D data;  //我们业务，需要的是moment视频播放进度

    //每个任务在什么时候执行（执行时间，或到期时间）
    private long deadlineNanos;


    /**
     *  构造方法
     * 1.计算每个任务的执行时间
     */
    public DelayTask(D data, Duration delayTime) {  //类的构造函数
        //任务的相关信息
        this.data = data;
        //当前时间 + 延迟时间 = 执行时间
        this.deadlineNanos = System.nanoTime() + delayTime.toNanos();
    }


    /**
     * 2.计算出离执行任务还剩多少时间。
     */
    @Override
    public long getDelay(TimeUnit unit) {
        //执行时间 - 当前时间 = 当前任务剩余时间
        //Math.max(0, deadlineNanos - System.nanoTime()) 取较大值： 如果剩余时间为负数，那么取0数值
        //unit.convert()：时间转换。将结果转为TimeUnit.NANOSECONDS 纳秒
        return unit.convert(Math.max(0, deadlineNanos - System.nanoTime()), TimeUnit.NANOSECONDS);
    }


    /**
     * 3.调用compareTo，根据当前任务的剩余延迟时间，将任务排序。
     * 任务的延迟时间越少则排在越前，越早执行。
     * 这里将元素（unit时间）比较，来进行排序。
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        //当前任务剩余时间 - 指定任务对象的剩余时间 = 进行比较，哪个大，哪个小
        long l = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
        if (l > 0) {
            return 1;    //表示当前任务的延迟时间，大于指定任务的延迟时间，那么排在后面执行。
        } else if (l < 0) {
            return -1;    //当前任务的延迟时间小于指定任务的延迟时间，则排在前面执行
        } else {
            return 0;
        }
    }
}